package com.zx.mes.hyl.controller;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.zx.mes.controller.BaseController;
import com.zx.mes.hyl.entity.*;
import com.zx.mes.hyl.pagemodel.TreeNode;
import com.zx.mes.hyl.service.SysRoleService;
import com.zx.mes.hyl.service.SysUserRoleService;
import com.zx.mes.hyl.service.SysUserService;
import com.zx.mes.hyl.utils.JWTHelper;
import com.zx.mes.response.ObjectRestResponse;
import com.zx.mes.response.TableResultResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * <p>
 *  控制器 SysUserController
 * </p>
 *
 * @author 华云龙
 * @since 2018-07-09
 */
@CrossOrigin
@RestController
@RequestMapping("/sysUser")
public class SysUserController extends BaseController<SysUserService,SysUser>{

    private static final Logger logger = LoggerFactory.getLogger(SysUserController.class);

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysRoleService sysRoleService;

    @Override
    public ObjectRestResponse<SysUser> add(SysUser sysUser) {
        sysUser.setId(UUID.randomUUID().toString());
        sysUser.setCreateDateTime(new Date());
        return super.add(sysUser);
    }

    @Override
    public ObjectRestResponse<SysUser> update(SysUser sysUser) {
        sysUser.setModifyDateTime(new Date());
        return super.update(sysUser);
    }

    @Override
    public TableResultResponse<SysUser> list(@RequestParam Map<String, Object> params, SysUser sysUser) {
        int page = Integer.valueOf(params.get("page").toString());
        int limit = Integer.valueOf(params.get("limit").toString());

        Wrapper<SysUser> wrapper = new EntityWrapper<>();
        if (sysUser != null && !"".equals(sysUser.getName())) {
            wrapper.like("name", sysUser.getName());
        }

        if (sysUser != null && sysUser.getCreateDateTimeStart()!=null) {
            wrapper.gt("createDateTimeStart", sysUser.getName());
        }
        if (sysUser != null && sysUser.getCreateDatetimeEnd()!=null) {
            wrapper.lt("createDatetimeEnd", sysUser.getName());
        }

        List<SysUser> list = this.biz.selectPage(new Page(page, limit),wrapper).getRecords();
        TableResultResponse<SysUser> response = null;
        if (list == null) {
            response = new TableResultResponse("无数据", 200, 0L, (long)page, (List)null);
        } else {
            response = new TableResultResponse("分页查询结果", 200, (long)this.biz.selectCount(new EntityWrapper()), (long)page, list);
        }

        return response;

    }

    @GetMapping("/loadUserByUsername")
    public SysUser loadUserByUsername(String name){
        SysUser sysUser = new SysUser();
        return sysUser.selectOne(new EntityWrapper<SysUser>().eq("name", name));
    }

    @Transactional(rollbackFor = Exception.class)
    @DeleteMapping("/deleteBatch")
    public ObjectRestResponse<String> deleteBatch(String ids) {
        ObjectRestResponse<String> response = new ObjectRestResponse<>();
        try {
            /// 删除sysUser表中对应的数据
            String[] idArr = ids.split(",");
            biz.deleteBatchIds(Arrays.asList(idArr));
            /// 删除中间表sysUserRole表中对应的数据
            sysUserRoleService.delete(new EntityWrapper<SysUserRole>()
                    .in("user_id", ids));
        } catch (Exception e) {
            response.setMessage(e.getMessage());
            response.setStatus(500);
            e.printStackTrace();
        }
        response.setMessage("批量删除成功!");
        return response;
    }

    @GetMapping("/login")
    public ObjectRestResponse<Jwt> login(SysUser sysUser){
        ObjectRestResponse<Jwt> response = new ObjectRestResponse<>();
        String token = null;
        try {
            SysUser user = biz.selectOne(
                    new EntityWrapper<SysUser>()
                            .eq("name", sysUser.getName())
                            .eq("password", sysUser.getPassword()));
            Jwt jwt = new Jwt();
            if (user != null) {
                jwt.setId(user.getId());
                jwt.setName(user.getName());
                token = JWTHelper.generateToken(jwt, "jwt/pri.key", 3600);
                jwt.setToken(token);
                response.setMessage("登录成功!");
                response.setData(jwt);
            } else {
                response.setMessage("登录失败，没有找到数据!");
                response.setStatus(500);
            }

        } catch (Exception e) {
            response.setMessage("登录失败:"+e.getMessage());
            response.setStatus(500);
            e.printStackTrace();
        }

        return response;
    }

    @GetMapping("/loadByUserName")
    public ObjectRestResponse<SysUser> loadByUserName(String token){
        Jws<Claims> claimsJws;
        ObjectRestResponse<SysUser> response = new ObjectRestResponse<>();
        try {
            claimsJws = JWTHelper.parserToken(token, "jwt/pub.key");
            Claims body = claimsJws.getBody();
            String name=body.getSubject();
            ///String id=body.get("id").toString();
            SysUser user = biz.loadByUserName(name);

            List<SysMenu> menuList = new ArrayList<>();
            for (int i = 0; i <user.getRoleList().size() ; i++) {
                menuList.addAll(user.getRoleList().get(i).getMenuList());
            }

            List<TreeNode> treeNodeList = new ArrayList<>();

            getRootNodes(menuList, treeNodeList);

            user.setTreeNodeList(treeNodeList);

            user.setPassword("");
            response.setMessage("获取用户详细信息成功!");
            response.setData(user);
        } catch (Exception e) {
            response.setMessage("获取用户信息失败:"+e.getMessage());
            response.setStatus(500);
            e.printStackTrace();
        }

        return response;
    }

    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/grantRole")
    public ObjectRestResponse<SysUser> grantRole(String userId,String roleIds){
        ObjectRestResponse<SysUser> response = new ObjectRestResponse();
        /// 先清掉所有的角色权限,in操作试用于mysql/oracle
        sysUserRoleService.delete(new EntityWrapper<SysUserRole>()
                                    .in("user_id",userId));

        /// 生成SysUerRole list集合
        String []roleId = roleIds.split(",");
        List<SysUserRole> list = new ArrayList<>();
        for (int i = 0; i <roleId.length ; i++) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setId(UUID.randomUUID().toString());
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId[i]);
            list.add(sysUserRole);
        }

        /// 再重写绑定
        sysUserRoleService.insertBatch(list, list.size());
        response.setMessage("授权成功!");
        return response;
    }


    @GetMapping("/loadRolesByUserId")
    public ObjectRestResponse<SysUser> loadRolesByUserId(String id){
        ObjectRestResponse<SysUser> response = new ObjectRestResponse<>();

        /// 通过中间表user-role这张表获取角色id
        List<SysUserRole> list = sysUserRoleService.selectList(
                new EntityWrapper<SysUserRole>()
                    .eq("user_id",id));

        List<String> roleIds = new ArrayList<>();
        for (int i = 0; i <list.size() ; i++) {
            roleIds.add(list.get(i).getRoleId());
        }
        /// 获取角色
        List<SysRole> roleList = sysRoleService.selectBatchIds(roleIds);

        SysUser sysUser = new SysUser();
        sysUser.setRoleList(roleList);
        sysUser.setId(id);

        return response.data(sysUser).rel(true);
    }


    private void getRootNodes(List<SysMenu> menuList, List<TreeNode> treeNodeList) {
        for (int i = 0; i <menuList.size() ; i++) {
            SysMenu sysMenu = menuList.get(i);
            String pid = sysMenu.getPid();
            if (pid == null || "".equals(pid)){
                TreeNode treeNode = new TreeNode();
                treeNode.setId(sysMenu.getId());
                treeNode.setKey(sysMenu.getId());
                treeNode.setLabel(sysMenu.getName());

                treeNode = getTree(treeNode,menuList);
                /// 添加
                treeNodeList.add(treeNode);
            }
        }
    }

    private TreeNode getTree(TreeNode treeNode, List<SysMenu> menuList) {
        for (int i = 0; i <menuList.size() ; i++) {
            SysMenu sysMenu = menuList.get(i);

            if (sysMenu.getPid()!=null&& sysMenu.getPid().equals(treeNode.getId())) {
                TreeNode node = new TreeNode();
                node.setId(sysMenu.getId());
                node.setKey(sysMenu.getId());
                node.setLabel(sysMenu.getName());
                /// 向children 添加
                treeNode.getChildren().add(node);
                /// 递归
                getTree(node, menuList);
            }
        }
        return treeNode;
    }

}

